﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.Deployment.TeamFoundation.Communication;
using PSE.Deployment.TeamFoundation.Entity;

namespace PSE.Deployment.TeamFoundation.Logic
{
    /// <summary>
    /// Classe que manipula as tasks para um Workspace
    /// É possível obter código fonte, criar branchs etc.
    /// </summary>
    public class WorkspaceTasks
    {
        #region [ Variaveis ]
        private static string _workspaceName;
        private static string _localPathMapping;
        #endregion [ Variaveis]

        #region [ Events ]
        public event EventHandler<PSE.Deployment.TeamFoundation.Entity.TraceEventArgs> TraceEvent;
        public event EventHandler<PSE.Deployment.TeamFoundation.Entity.FileEventArgs> FileDownloadedEvent;
        #endregion [ Events ]

        #region [ Constructor ]

        /// <summary>
        /// Construtor da Classe
        /// </summary>
        public WorkspaceTasks()
        {
            Initialize(string.Empty, string.Empty);
        }

        /// <summary>
        /// Construtor da Classe
        /// </summary>
        public WorkspaceTasks(string workspaceName, string localPathMapping)
        {
            Initialize(workspaceName, localPathMapping);
        }
        #endregion [ Constructor ]

        /// <summary>
        /// Inicializa os parâmetros principais da classe
        /// </summary>
        /// <param name="workspaceName">Nome do Workspace</param>
        /// <param name="localPathMapping">Local onde o workspace será mapeado</param>
        private void Initialize(string workspaceName, string localPathMapping)
        {
            _workspaceName = (string.IsNullOrEmpty(workspaceName)) ? CreateTemporaryName() : workspaceName;
            _localPathMapping = (string.IsNullOrEmpty(localPathMapping)) ? string.Format("{0}/{1}", System.Environment.GetEnvironmentVariable("TEMP"), CreateTemporaryName()) : localPathMapping;

            WorkspaceClient.Instance.FileDownloaded += (sender, e) =>
            {
                if(FileDownloadedEvent != null)
                    FileDownloadedEvent(sender, e);
            };

            WorkspaceClient.Instance.TraceEvent += (sender, e) =>
            {
                if(TraceEvent != null)
                    TraceEvent(sender, e);
            
            };

            WorkspaceClient.Instance.MappingWorkspace(_workspaceName, _localPathMapping);        
        }

        /// <summary>
        /// Obtém um código fonte
        /// </summary>
        /// <param name="sourcePath">Caminho do código fonte</param>
        /// <param name="targetPath">Caminho onde será baixado o código fonte</param>
        public void GetSource(string sourcePath, string targetPath)
        {
            if (string.IsNullOrEmpty(sourcePath))
                throw new ArgumentNullException("sourcePath");

            if (string.IsNullOrEmpty(targetPath))
                throw new ArgumentNullException("targetPath");

            SourceRequest request = new SourceRequest();
            request.SystemName = string.Empty;
            request.SourceUri = sourcePath;
            request.DownloadPath = targetPath;

            WorkspaceClient.Instance.GetSource(_workspaceName, sourcePath, targetPath);
        }

        /// <summary>
        /// Cria um Branch
        /// </summary>
        /// <param name="sourcePath">Caminho do código fonte</param>
        /// <param name="targetPath">Caminho onde será baixado o código fonte</param>
        public void CreateBranch(string sourcePath, string targetPath)
        {
            CreateBranch(sourcePath, targetPath, false);
        }

        /// <summary>
        /// Cria um Branch
        /// </summary>
        /// <param name="sourcePath">Caminho do código fonte</param>
        /// <param name="targetPath">Caminho onde será baixado o código fonte</param>
        /// <param name="updateDisk">Indica se o código será baixado pro disco ou não</param>
        public void CreateBranch(string sourcePath, string targetPath, bool updateDisk)
        {
            if (string.IsNullOrEmpty(sourcePath))
                throw new ArgumentNullException("sourcePath");

            if (string.IsNullOrEmpty(targetPath))
                throw new ArgumentNullException("targetPath");

            WorkspaceClient.Instance.CreateBranch(_workspaceName, sourcePath, targetPath, updateDisk);
        }

        /// <summary>
        /// Efetua o checkin das alterações feitas nesse workspace
        /// </summary>
        /// <param name="message">Mensagem para o checkin</param>
        public void CheckIn(string message)
        {
            if (string.IsNullOrEmpty(message))
                throw new ArgumentNullException("message");

            WorkspaceClient.Instance.CheckIn(_workspaceName, message);
        }

        /// <summary>
        /// Adiciona um arquivo ou pasta ao workspace
        /// </summary>
        /// <param name="path">Caminho do arquivo ou pasta</param>
        public void AddFileOrFolder(string path)
        {
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path");

            WorkspaceClient.Instance.AddFileOrFolder(_workspaceName, path);
        }
        /// <summary>
        /// Deleta um arquivo ou pasta do workspace
        /// </summary>
        /// <param name="path">Caminho do arquivo ou pasta</param>
        public void DeleteFileOrFolder(string path)
        {
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path");

            WorkspaceClient.Instance.DeleteFileOrFolder(_workspaceName, path);
        }

        /// <summary>
        /// Desfaz todas as alterações efetuadas no workspace
        /// </summary>
        public void Undo()
        {
            WorkspaceClient.Instance.Undo(_workspaceName, true);
        }

        /// <summary>
        /// Exclui um workspace
        /// </summary>
        public void DeleteWorkspace()
        {
            WorkspaceClient.Instance.DeleteWorkspace(_workspaceName);
        }

        /// <summary>
        /// Cria um nome para um workspace  temporário
        /// </summary>
        /// <returns>Nome para um workspace  temporário</returns>
        private string CreateTemporaryName()
        {
            Random random = new Random();
            random.Next();
            return random.Next().ToString() + "TemporaryWorkspace";
        }
    }
}
